import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt


#读取每种期货目标持仓和对应时间的历史数据并合并，返回合并后的dataframe和期货种类categories
def readAndMerge(target):
    
    #SampleTarget和SampleTarget2的基数是1，SampleTarget1基数是100万，通过multiplier进行统一
    multiplier = 1000000
    if target == 'SampleTarget1':
        multiplier = 1
    
    #读取目标持仓
    base_path = 'C:/Users/ASUS/Desktop/Py-data'
    df0 = pd.read_csv(base_path + '/' + target + '.csv')
    categories = df0.columns[2:]
    
    #读取1m数据并合并
    ft_path = base_path + '/1m'
    files = os.listdir(ft_path)
    for file in files:
        name = file[:-3]
        if name in categories:
            df1 = pd.read_feather(ft_path + '/' + file, columns=['trading_day','timestamp','clz'])
            df0 = pd.merge(df0,df1,on=['trading_day','timestamp'],how='left')  #以df0中的数据为基准合并df1
            df0 = df0.rename(columns={'clz': name+'_price'})
    
    #处理NaN:仓位处NaN替换为0，收盘价中clz前向填充
    for category in categories:
        df0[category] = df0[category] * multiplier #基数统一换算为100W
        df0[category].fillna(0, inplace=True)
        df0[category+'_price'].fillna(method='ffill', inplace=True)

    # 将仓位不为0但价格为0的数据视为异常，把仓位改为0
    for category in categories:
        df0.loc[(df0[category]!=0) & (df0[category+'_price']!=df0[category+'_price']),category] = 0

    return df0, categories

#指标计算
def indicators(df,categories):
    for category in categories:
        # 市值/收盘价=持有量
        df[category+'_vol'] = df[category] / df[category+'_price']
        df[category+'_vol'].fillna(0, inplace=True)
        # 1时点pnl=（1时点价格-0时点价格）*0时点持有量 
        df[category+'_pnl'] = (df[category+'_price'] - df[category+'_price'].shift(periods=-1, axis=0)) * df[category+'_vol']
        df[category+'_pnl'].fillna(0, inplace=True)
        # 1时点turnover=1时点目标持仓市值-1时点价格*0时点持有量
        df[category+'_turnover'] = df[category] - df[category+'_price'] * df[category+'_vol'].shift(periods=-1, axis=0)
        df[category+'_turnover'].fillna(0, inplace=True)
        # fee=turnover的绝对值*费率
        df[category+'_fee'] = abs(df[category+'_turnover'] * 3 / 10000)
        # net_pnl=pnl-fee
        df[category+'_net_pnl'] = df[category+'_pnl'] - df[category+'_fee']
    
    #将各品种的数据加总得到每日所有品种各指标总和
    df['total_pnl'] = 0
    df['total_pnl_net'] = 0
    df['total_fee'] = 0
    df['total_turnover'] = 0
    df['total_marketvalue'] = 0
    for category in categories:
        df['total_pnl'] += df[category+'_pnl']
        df['total_pnl_net'] += df[category+'_net_pnl']
        df['total_fee'] += df[category+'_fee']
        df['total_turnover'] += df[category+'_turnover']
        df['total_marketvalue'] += df[category]
    
    #计算累计值
    def addup(name):
        add = 0
        addup_lst = []
        addup_lst.append(add)
        for indicator in df[name][1:]:
            add += indicator
            addup_lst.append(add)
        df[name+'_addup'] = addup_lst
    addup('total_pnl')
    addup('total_pnl_net')
    addup('total_fee')

    return df

#作图
def print_picture(df):
        
    # 将trading_day改为日期格式
    df['trading_day'] = pd.to_datetime(df['trading_day'],format='%Y%m%d')
    
    # 计算三个指标
    SharpRatio = df['total_pnl_net'].mean() / (df['total_pnl_net'].std() * 15.8) *np.sqrt(240)
    TurnOver = df['total_turnover'].mean()
    AvgLeverage = df['total_marketvalue'].mean()
    
    # 画图
    plt.figure(figsize=(18,9))
    plt.plot(df['trading_day'], df['total_pnl_net'], 'r', label='pnl_net')
    title = 'SharpRatio: ' + str(round(SharpRatio,4)) + ', TurnOver: ' + str(round(TurnOver,4)) + ', AvgLeverage: ' + str(round(AvgLeverage,4))
    plt.title(title)
    plt.legend()
    plt.show()

target = 'SampleTarget' + input()
df,categories = readAndMerge(target)
print_picture(indicators(df,categories))